<?php

namespace App\Traits;

use GuzzleHttp\Client;

/**
 * Http 请求辅助类 Trait
 *
 * @author WangBin
 * @date 2021/8/18
 */
trait HttpHelper
{
    /**
     * 调用外部 Http 请求
     *
     * @param string $url
     * @param string $method
     * @param array $data
     * @return \Psr\Http\Message\ResponseInterface|null
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @author WangBin
     * @date 2021/8/18
     */
    public function sendRequest(string $url, string $method, array $data)
    {
        $client = new Client(["verify"=>false, 'timeout' => 60]);
        $method = strtoupper($method);
        $response = null; // 返回数据
        switch ($method)
        {
            case 'GET':
                $response = $client->get($url, [
                    'query' => $data
                ]);
                break;
            case 'POST':
                $response = $client->post($url, [
                    'json' => $data,
                    'headers' => [
                        'Content-Type' => 'application/json'
                    ]
                ]);
                break;
        }
        return $response;
    }

    /**
     * 发送 get 请求
     *
     * @param string $url
     * @param array $proxy
     * @param array $header
     * @return \Psr\Http\Message\ResponseInterface
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function sendGet(string $url, array $proxy = [], array $header = [])
    {
        $param = ["verify"=>false, 'timeout' => 30];
        if($proxy) {
            $param['proxy'] = $this->proxy;
        }
        if($header) {
            $param['headers'] = $header;
        }
        $client = new Client($param);
        return $client->request('GET', $url);
    }

    /**
     * 发送 post 请求
     *
     * @param string $url
     * @param $data
     * @param array $proxy
     * @param array $header
     * @return \Psr\Http\Message\ResponseInterface
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function sendPost(string $url, $data, array $proxy = [], array $header = [])
    {
        $client = new Client(["verify"=>false, 'timeout' => 30]);
        $headers = !empty($header) ? $header : ['Content-Type' => 'application/json;charset=utf-8'];

        $response = $client->post($url, [
            'json' => $data,
            'headers' => $headers,
            'proxy' => $proxy,
        ]);
        return $response;
    }

    /**
     * 发送 post 请求
     *
     * @param string $url
     * @param $data
     * @param array $proxy
     * @param array $header
     * @return \Psr\Http\Message\ResponseInterface
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function sendXmlPost(string $url, $data, array $proxy = [], array $header = [])
    {
        $client = new Client(["verify"=>false, 'timeout' => 30]);
        $headers = !empty($header) ? $header : ['Content-Type' => 'application/xml;charset=utf-8'];

        $response = $client->post($url, [
            'body' => $data,
            'headers' => $headers,
            'proxy' => $proxy,
        ]);
        return $response;
    }


    /**
     *  发送 post 请求
     *
     * @param string $url
     * @param $data
     * @param array $proxy
     * @param array $header
     * @param string $cert
     * @param string $key
     * @return \Psr\Http\Message\ResponseInterface
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function sendVerifyXmlPost(string $url, $data, array $proxy = [], array $header = [],string $cert,string $key)
    {
        $client = new Client(["verify"=>false, 'timeout' => 30]);
        $headers = !empty($header) ? $header : ['Content-Type' => 'application/xml;charset=utf-8'];

        $response = $client->post($url, [
            'body' => $data,
            'headers' => $headers,
            'proxy' => $proxy,
            'cert'=> $cert,
            'ssl_key' => $key,
        ]);
        return $response;
    }

    /**
     * 发送 post form-data 请求
     *
     * @param string $url
     * @param array $data
     * @param array $proxy = []
     * @return \Psr\Http\Message\ResponseInterface
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function sendFormDataPost(string $url, array $data, array $proxy = [])
    {
        $client = new Client(["verify"=>false, 'timeout' => 30]);
        $response = $client->post($url, [
            'form_params' => $data,
            'proxy' => $proxy
        ]);
        return $response;
    }

    /**
     * 发送 post x-www-form-urlencoded 请求
     *
     * @param string $url
     * @param array $data
     * @param array $proxy = []
     * @return \Psr\Http\Message\ResponseInterface
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function sendFormUrlencodedPost(string $url, array $data, array $proxy = [])
    {
        $client = new Client(["verify"=>false, 'timeout' => 30]);
        $headers = ['Content-Type' => 'application/x-www-form-urlencoded'];
        $response = $client->post($url, [
            'form_params' => $data,
            'headers' => $headers,
            'proxy' => $proxy
        ]);
        return $response;
    }

    /**
     * curl get 请求
     *
     * @param string $url
     * @return bool|string
     */
    public function sendGetCurl(string $url)
    {
        // 初始化一个新会话
        $ch = curl_init();
        // 设置要求请的url
        curl_setopt($ch, CURLOPT_URL, $url);
        // 是否验证SSL证书
        // 一般不验证 ( 默认为验证 需设置fasle关闭 )
        // 如果设置false报错 尝试改为 0
        // 某些CURL版本不只true和fasle两种状态 可能是0,1,2...等
        // 如果选择验证证书 将参数设置为ture或1
        // 然后在使用CURLOPT_CAPATH和CURLOPT_CAINFO设置证书信息
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        // 验证证书中域名是否与当前域名匹配 和上面参数配合使用
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        // 是否将数据已返回值形式返回
        // 1 返回数据
        // 0 直接输出数据 帮你写了: echo $output;
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT , 30);
        // 执行CURL请求
        $output = curl_exec($ch);
        // 关闭CURL资源
        curl_close($ch);
        // 输出返回信息
        return $output;
    }
}
